package com.mirabelle.juice.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Paginator<T> implements Serializable {
	private static final long serialVersionUID = 1L;
	
	/*
	 * Liste a découper
	 */
	private List<T> list = null;
	/*
	 * Taille d'une page
	 */
	private int ssize = 4;
	/*
	 * Nombre de pages calculées
	 */
	//private int psize = 0; // fake, calculé dans le gettre. Jamais mis à jour
	/*
	 * Liste des pages de taille ssize
	 */
	private List<List<T>> pages = null;
	/*
	 * Index interne
	 */
	private int index = 0;
	
	public Paginator() {
	}
	
	public Paginator(List<T> list, int ssize) {
		this.list = list;
		this.ssize = ssize;
		createSlices();
	}
	
	/**
	 * Fixe la liste d'objets à paginer en positionnant l'index sur la dernière page possible
	 * @see reSetList
	 */
	public void setList(List<T> list) {
		this.list = list;
		createSlices();
	}
	
	/**
	 * Fixe la liste d'objets à paginer en positionnant l'index sur la premiere page
	 * @see setList
	 */
	public void reSetList(List<T> list) {
		this.index = 0;
		this.list = list;
		createSlices();
	}
	
	/**
	 * Fixe la liste d'objets à paginer en positionnant l'index sur la dernière page possible
	 * et en fixant le nombre d'objet par page
	 * @see reSetList
	 */
	public void setList(List<T> list, int ssize) {
		this.list = list;
		this.ssize = ssize;
		createSlices();
	}
	
	/**
	 * Fixe la liste d'objets à paginer en positionnant l'index sur la premiere page
	 * et en fixant le nombre d'objet par page
	 * @see setList
	 */
	public void reSetList(List<T> list, int ssize) {
		this.index = 0;
		this.list = list;
		this.ssize = ssize;
		createSlices();
	}
	
	private void createSlices() {
		pages = new ArrayList<List<T>>();
		int i=0;
		while (i<list.size()) {
			pages.add(list.subList(i, (i+ssize > list.size()) ? list.size() : i+ssize)); 
			i+=ssize;
		}
		//System.err.println(pages.size() + " pages crées, l'index est : " + index );
		if ((index >= pages.size())&&(pages.size() > 0)) {
			index = pages.size() - 1;
			//System.err.println("l'index est décrementé à : " + index );
		}
	}
	
	public void setSsize(int ssize) {
		this.ssize = ssize;
		createSlices();
	}
	
	public int getSsize() {
		return ssize;
	}
	
	public int getPsize() {
		return pages.size();
	}
	
	public List<List<T>> getAllPages() {
		return pages;
	}
	
	public List<T> getPage(int index) {
		this.index = index;
		try {
			return pages.get(index);
		} catch (IndexOutOfBoundsException e) {
			//
		}
		return new ArrayList<T>();
	}
	
	public boolean hasNext() {
		return index < (pages.size() - 1);
	}
	
	public boolean hasPrevious() {
		return index > 0;
	}
	
	public List<T> getNext() {
		if (index < list.size()) {
			index++;
		}
		return pages.get(index);
	}
	
	public List<T> getPrevious() {
		if (index > 0) {
			index--;
		}
		return pages.get(index);
	}
	
	public int getIndex() {
		return index;
	}
	
	public int getDisplayIndex() {
		return index + 1;
	}
	
	public List<T> getLast() {
		index = pages.size() - 1;
		return pages.get(index);
	}
	
	public List<T> getCurrent() {
		
		//System.err.println("Liste de " + list.size() + " elements découpées en " + getPsize() + " tranches de " + ssize + " elements"); 
		//System.err.println("Index courant : " + index + " hasNext : " + hasNext() + " hasPrevious : " + hasPrevious()); 
		
		try {
			return pages.get(index);
		} catch (IndexOutOfBoundsException e) {
			//
		}
		return new ArrayList<T>();
	}
}
